package com.watchmen.mini.modules.sys.interceptor;


import com.watchmen.mini.common.config.Global;
import com.watchmen.mini.common.utils.IdGen;
import com.watchmen.mini.common.utils.RedisUtil;
import com.watchmen.mini.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class CacheTokenManager implements TokenManager {

    private RedisUtil redisUtil = new RedisUtil();

    private static Logger logger = LoggerFactory.getLogger(RedisUtil.class);

    private static final String KEY_PREFIX = Global.getConfig("redis.keyPrefix");

    /*
     * loginName 作为key
     * TokenModel 对象作为 value
     */
    @Override
    public TokenModel createToken(TokenModel model) {
        String oldTokenCode = (String) redisUtil.get(model.getDevice()+"_"+model.getLoginName());
        if (StringUtils.isBlank(oldTokenCode)) {// 找不到，新创建
            String tokenCode = model.getDevice()+"_"+ IdGen.uuid().toString().replace("-", "");
            model.setToken(tokenCode);
            //将token放入缓存
            redisUtil.set(tokenCode, model, Constants.TOKEN_EXPIRES_MIN);
            redisUtil.set(model.getDevice()+"_"+model.getLoginName(), tokenCode, Constants.TOKEN_EXPIRES_MIN); //用户：tokenCode
            logger.info("oldToken == null ,so create new token;user:{};new token:{}", model.getLoginName(), tokenCode);
            return model;
        } else {
            TokenModel oldToken = (TokenModel) redisUtil.get(oldTokenCode);
            oldToken.setCasInfo(model.getCasInfo());
            if (Global.getConfig("user.multiAccountLogin", "true").equals("false")) { //如果是单用户，则把old置为true，然后新建一个token到前端
                oldToken.setExpire(true);
                oldToken.setCasInfo(null);
                oldToken.setLoginName(null);
                redisUtil.set(oldTokenCode, oldToken, 5l); //只保留token的对象
                redisUtil.remove(model.getDevice()+"_"+model.getLoginName());
                //然后在新建一个token返回
                String tokenCode = model.getDevice()+"_"+IdGen.uuid().toString().replace("-", "");
                model.setToken(tokenCode);
                //将token放入缓存
                redisUtil.set(tokenCode, model, Constants.TOKEN_EXPIRES_MIN);
                redisUtil.set(model.getDevice()+"_"+model.getLoginName(), tokenCode, Constants.TOKEN_EXPIRES_MIN); //用户：tokenCode
                logger.info("oldToken == null ,so create new token;user:{};new token:{}", model.getLoginName(), tokenCode);
                return model;
            } else { //如果不是，则沿用原来的token，只刷新时间
                redisUtil.set(oldTokenCode, oldToken, Constants.TOKEN_EXPIRES_MIN);
                redisUtil.set(model.getDevice()+"_"+model.getLoginName(), oldTokenCode, Constants.TOKEN_EXPIRES_MIN);
                logger.info("oldToken != null ,so update token;user:{}; old token:{}", model.getLoginName(), oldTokenCode);
            }
            return oldToken;
        }
    }

    @Override
    public boolean checkToken(String tokenCode) {
        if (StringUtils.isBlank(tokenCode)) {
            return false;
        }
        TokenModel token = (TokenModel) redisUtil.get(tokenCode);
        if (token == null) {
            return false;
        }

        //如果验证成功，说明此用户进行了一次有效操作，延长token的过期时间
        redisUtil.set(tokenCode, token, Constants.TOKEN_EXPIRES_MIN);
        redisUtil.set(token.getDevice()+"_"+token.getLoginName(), tokenCode, Constants.TOKEN_EXPIRES_MIN);
        return true;
    }

    @Override
    public TokenModel getToken(String tokenCode) {
        if (StringUtils.isBlank(tokenCode)) {
            return null;
        }
        TokenModel token = (TokenModel) redisUtil.get(tokenCode);
        return token;
    }


    @Override
    public TokenModel getTokenByLoginName(String loginName) {
        String tokenCode = (String) redisUtil.get(loginName);
        TokenModel token = (TokenModel) redisUtil.get(tokenCode);
        return token;
    }


    @Override
    public void deleteToken(String loginName) {
        String tokenCode = (String) redisUtil.get(loginName);
        TokenModel token = (TokenModel) redisUtil.get(tokenCode);
        if (token != null) {
            redisUtil.remove(tokenCode);
            redisUtil.remove(token.getDevice()+"_"+token.getLoginName());
        }
    }

    @Override
    public void deleteTokenByCode(String tokenCode) {
        TokenModel token = (TokenModel) redisUtil.get(tokenCode);
        if (token != null) {
            redisUtil.remove(tokenCode);
            redisUtil.remove(token.getDevice()+"_"+token.getLoginName());
        }
    }

    public String setPrefix(String key) {
        key = KEY_PREFIX + "_" + key;
        return key;
    }
}
